unit db_dealitem;

interface

uses
  define_dealitem, BaseDataSet, QuickList_DealItem,
  Define_DealMarket, define_dealstore_header;
  
type
  TDBDealItem = class(TBaseDataSetAccess)
  protected
    fDealItemList: TDealItemList;
    function GetRecordCount: Integer; override;  
    function GetRecordItem(AIndex: integer): Pointer; override;
    function GetItem(AIndex: integer): PRT_DealItem; overload;
    function GetItem(ACode: string): PRT_DealItem; overload;
  public
    constructor Create(ADBType, ADataSrcId: integer); override;
    destructor Destroy; override;   
    class function DataTypeDefine: integer; override;
    procedure Sort; override;
    procedure Clear; override;
    function AddDealItem(AMarketCode, AStockCode: AnsiString): PRT_DealItem;  
    function FindDealItemByCode(AStockCode: AnsiString): PRT_DealItem;
    function CheckOutDealItem(AMarketCode, AStockCode: AnsiString): PRT_DealItem;
    
    function DealItemByIndex(AIndex: integer): PRT_DealItem;
    
    property Items[AIndex: integer]: PRT_DealItem read GetItem;       
    property Item[ACode: string]: PRT_DealItem read GetItem;
  end;

  PStore_Header     = ^TStore_Header;
  TStore_Header     = packed record // 128
    CommonHeader    : TStore_Common_Header_V1;
    Code            : array[0..11] of AnsiChar; // 12 - 32
  end;

  PStore_HeaderRec  = ^TStore_HeaderRec;
  TStore_HeaderRec  = packed record // 128
    Header          : TStore_Header;        
    Reserve         : array[0..64 - 1 - SizeOf(TStore_Header)] of Byte;
  end;
//*)
implementation

uses
  SysUtils,
  define_dealstore_file,
  QuickSortList;

constructor TDBDealItem.Create(ADBType, ADataSrcId: integer); 
begin
  inherited Create(ADBType, ADataSrcId); 
  fDealItemList := TDealItemList.Create;
  fDealItemList.Duplicates := QuickSortList.lstdupIgnore;
end;

destructor TDBDealItem.Destroy;
begin
  Clear;
  fDealItemList.Free;
  inherited;
end;

class function TDBDealItem.DataTypeDefine: integer;
begin
  Result := DataType_Item;
end;

function TDBDealItem.GetRecordItem(AIndex: integer): Pointer;
begin
  Result := Pointer(fDealItemList.DealItem[AIndex]);
end;

function TDBDealItem.GetItem(AIndex: integer): PRT_DealItem;
begin
  Result := GetRecordItem(AIndex);
end;

function TDBDealItem.GetItem(ACode: string): PRT_DealItem;
begin
  Result := nil;
end;

function TDBDealItem.GetRecordCount: integer;

begin
  Result := fDealItemList.Count;
end;

procedure TDBDealItem.Sort;
begin
  fDealItemList.Sort;
end;
          
procedure TDBDealItem.Clear;
var
  i: integer;
  tmpDealItem: PRT_DealItem;
begin
  for i := fDealItemList.Count - 1 downto 0 do
  begin
    tmpDealItem := fDealItemList.DealItem[i];
    FreeMem(tmpDealItem);
  end;
  fDealItemList.Clear;
end;

function TDBDealItem.AddDealItem(AMarketCode, AStockCode: AnsiString): PRT_DealItem;
var   
  tmpPackStockCode: integer;
  tmpIndex: integer;
begin
  if 6 > Length(AStockCode) then
  begin
    tmpPackStockCode := getStockCodePack(AStockCode);
  end else
  begin
    if 6 = Length(AStockCode) then
    begin
      if '6' = AStockCode[1] then
      begin
        tmpPackStockCode := getStockCodePack(AStockCode);
      end else
      begin
        tmpPackStockCode := getStockCodePack(AStockCode);
      end;
    end else
    begin
      tmpPackStockCode := getStockCodePack(AStockCode);
    end;
  end;
  tmpIndex := fDealItemList.IndexOf(tmpPackStockCode);   
  if tmpIndex < 0 then
  begin
    Result := System.New(PRT_DealItem);
    FillChar(Result^, SizeOf(TRT_DealItem), 0);
    Result.DBType := Self.DBType;   
    Result.iCode := StrToIntDef(AStockCode, 0);
    fDealItemList.AddDealItem(tmpPackStockCode, Result);    
    Result.sMarketCode := AMarketCode;
    Result.sCode := getSimpleStockCodeByPackCode(Result.iCode);
  end else
  begin
    Result := fDealItemList.DealItem[tmpIndex];
    Result.sMarketCode := AMarketCode;
    Result.sCode := getSimpleStockCodeByPackCode(Result.iCode);
  end;                         
end;

function TDBDealItem.DealItemByIndex(AIndex: integer): PRT_DealItem;
begin
  Result := GetRecordItem(AIndex);
end;

function TDBDealItem.FindDealItemByCode(AStockCode: AnsiString): PRT_DealItem;
var
  tmpIndex: integer;
  tmpPackStockCode: integer;
begin
  Result := nil;
  tmpPackStockCode := 0;
  if 6 < Length(AStockCode) then
  begin
    tmpPackStockCode := getStockCodePack(Copy(AStockCode, Length(AStockCode) - 6 + 1, MaxInt));
  end else if 6 = Length(AStockCode) then
  begin
    tmpPackStockCode := getStockCodePack(AStockCode);
  end else if 6 > Length(AStockCode) then
  begin
    tmpPackStockCode := getStockCodePack(AStockCode);
  end;
  if 0 < tmpPackStockCode then
  begin
    tmpIndex := fDealItemList.IndexOf(tmpPackStockCode);
    if 0 <= tmpIndex then
    begin
      Result := fDealItemList.DealItem[tmpIndex];
    end;
  end;
end;

function TDBDealItem.CheckOutDealItem(AMarketCode, AStockCode: AnsiString): PRT_DealItem;
begin
  Result := FindDealItemByCode(AMarketCode + AStockCode);
  if nil = Result then
  begin
    Result := AddDealItem(AMarketCode, AStockCode);
  end;
end;

end.
